/*
 * Copyright (C) 2011 Mette Bank, Rikke Jensen, Kenneth Brodersen, Thomas Pedersen
 * 
 * This file is part of digiPECS.
 * 
 * digiPECS is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * digiPECS is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with digiPECS.  If not, see <http://www.gnu.org/licenses/>.
 */

package sw6.digipecs.user;

import sw6.digipecs.R;
import sw6.girafAppKit.GirafActivity;
import android.content.Intent;
import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
import android.os.SystemClock;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.ImageView;

/** 
 * 
 * This activity is first entry point of the pigipecs application. The activity will run within
 * a predefined time frame and will start and initialise the main activity on the user side. 
 * The main purpose with this activity is to provide a splash screen to the digipecs application 
 * that will run an animation for a defined amount of time but can exited by touching the screen.
 * Any heavy duty work with initialising the application can run while this activity is active and 
 * before the Main Activity is initialised..
 * 
 *  * @author sw6.digipecs
 */
public class SplashActivity extends GirafActivity {
	
	private Thread mSplashThread;
	private Thread mWorkerThread;
	private final int SPLASH_TIME_DELAY = 4000;
	private long mTimeLeft = 0L;
	private ImageView mSplashImageView;
	private AnimationDrawable mFrameAnimation;
	private static final String TIME_LEFT_STATE = "TIME_LEFT_STATE";
	private static final String LOG_STRING = "sw6.digipecs";
	
	/**
	 * @see android.app.Activity#onCreate(Bundle)
	 */
	@Override
	public void onCreate(Bundle bundle) {
		super.onCreate(bundle);
		
		Log.v(LOG_STRING, "on create is run");
		
		setContentView(R.layout.splashactivity);
		
		mSplashImageView = (ImageView) findViewById(R.id.splash_imageviev);
		mSplashImageView.setBackgroundResource(R.drawable.frame_anim);
		mFrameAnimation = (AnimationDrawable) mSplashImageView.getBackground();
		
		
		if(bundle != null && bundle.containsKey(TIME_LEFT_STATE))
		{
			mTimeLeft = bundle.getLong(TIME_LEFT_STATE);
		}
		else{
			mTimeLeft = SPLASH_TIME_DELAY;
		}
		
		mWorkerThread = new Thread() {
			@Override
			public void run() {
				// TODO What to run during splash screen ???
			}
		};
		
		mWorkerThread.setDaemon(true);
		mWorkerThread.start();
	}
	
	/**
	 * Used to save state in the bundle - are not using onPause, cos we 
	 * don't want to save this information in case the onBackButton() is called
	 */
	@Override
	protected void onSaveInstanceState(Bundle bundle) {
		
		mSplashThread.interrupt();
		try {
			mSplashThread.join();
			bundle.putLong(TIME_LEFT_STATE, mTimeLeft);
			Log.v("sw6", "Time " + Long.toString(mTimeLeft) + " saved");
		} catch (InterruptedException e) {
			//has been handled by calling
		}
		
		super.onSaveInstanceState(bundle);
	}

	/**
	 * Used to stop the animation, so its not running unnecessary the moment the 
	 * activity is not in focus
	 * @see android.app.Activity#onPause()
	 */ 
	@Override
	protected void onPause() {
		super.onPause();
		
		mSplashImageView.post(new Runnable() {
			@Override
			public void run() {
				mFrameAnimation.stop();
			}
		});
		
		mSplashThread.interrupt();
	}
	
	/**
	 * The onResume will start the animation of the splash screen in a new thread  
	 * to ensure that the splash screen will be active for at least SPLASH_TIME_DELAY 
	 * amount of time
	 * @see android.app.Activity#onResume
	 */
	@Override
	protected void onResume() {
		super.onResume();
		
		mSplashImageView.post(new Runnable() {
			@Override
			public void run() {
				mFrameAnimation.start();
			}
		});
	
		final SplashActivity sPlashScreen = this;
		mSplashThread =  new Thread(){
			@Override
            public void run(){
				long startMillis = 0L;
            	try {
                    synchronized(this){
                    	startMillis = SystemClock.uptimeMillis();
                        wait(mTimeLeft);
                    }
                }
                catch(InterruptedException ex){
                	// When thread is interrupted this code will be executed...
                	
                	long leftMillis = SystemClock.uptimeMillis();
                	mTimeLeft = mTimeLeft - (leftMillis - startMillis);
                	
                	Log.v("sw6", "Thread stopped - Interrupted");
                	return;
                }
                
                // Make sure that worker thread is finished before we load activity
                try {
					mWorkerThread.join();
				} catch (InterruptedException e) {
					Log.v("sw6", "Thread stopped - Interrupted");
                	return;
				}
                
                // Finish the splash activity, so that it is destroyed correct, e.g. state is not saved
                finish();

                // Run next activity
                Intent intent = new Intent();
                intent.setClass(sPlashScreen, MainActivity.class);
                startActivity(intent);
            }
        };
        
        //setDeamon ensures threads associated with that application are killed when the application�s main thread is killed.
        mSplashThread.setDaemon(true);
        mSplashThread.start(); 
	}

	/**
	 * Manages skipping the splash screen with a touch event by handling the onTouchEvent and stops 
	 * the wait method on the mSplashThread without throwing an interrupt exception.
	 * @see android.app.Activity#onTouchEvent(MotionEvent)
	 */
	@Override
	public boolean onTouchEvent(MotionEvent eventTouch){
		if(eventTouch.getAction() == MotionEvent.ACTION_DOWN)
		{
			synchronized (mSplashThread) {			
				mSplashThread.notifyAll();
			}
		}
		return true;
	}
	
}
